home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Languages
/
MacMETH 3.2.3
/
More Examples
/
Newton.MOD
< prev
next >
Wrap
Text File
|
1995-12-13
|
6KB
|
240 lines
MODULE Newton; (* HS 19.10.91 *)
FROM SYSTEM IMPORT Exp, Ln, Sqrt, Sin, Cos, ArcTan;
FROM Terminal IMPORT BusyRead;
FROM CursorMouse IMPORT GetMouse;
FROM InOut IMPORT Read, Write, WriteString, WriteLn;
FROM Windows IMPORT SetWindow, ResetWindow;
FROM GraphicWindows IMPORT Window, OpenGraphicWindow, CloseGraphicWindow, Clear,
SetPen, MoveTo, Dot, IdentifyPos;
CONST NrPixels = 256;
(* colours *)
white = 449;
yellow = 65;
green = 321;
zyan = 257;
blue = 385;
magenta = 129;
red = 193;
black = 1;
VAR ch : CHAR;
v,w : Window;
environ : BITSET;
ox,oy,nx,ny : INTEGER;
dx,dy,max,p,q : REAL;
xmax,xmin : REAL;
ymax,ymin : REAL;
ux,uy,uux,uuy : REAL;
deltax : INTEGER;
maxiter : INTEGER;
this : INTEGER;
PROCEDURE f(x: REAL): REAL;
BEGIN
RETURN x * Cos(6.0*x) * Exp(-x*x)
END f;
PROCEDURE ForeColour(c : LONGINT); CODE 0A862H;
PROCEDURE BackColour(c : LONGINT); CODE 0A863H;
PROCEDURE Colour(k : INTEGER);
VAR c : LONGINT;
BEGIN
IF k >= maxiter THEN c := black
ELSE
k := k MOD 16;
CASE k OF
0 : c := white;
| 1 : c := yellow;
| 2 : c := yellow;
| 3 : c := green;
| 4 : c := green;
| 5 : c := zyan;
| 6 : c := zyan;
| 7 : c := blue;
| 8 : c := blue;
| 9 : c := blue;
|10 : c := magenta;
|11 : c := magenta;
|12 : c := magenta;
|13 : c := red;
|14 : c := red;
|15 : c := red;
END;
END;
ForeColour(c);
END Colour;
PROCEDURE GetPos(VAR i,j: INTEGER);
CONST ML = 15;
VAR mouse : BITSET; x,y : INTEGER;
BEGIN mouse := {};
REPEAT GetMouse(mouse,x,y) UNTIL NOT(ML IN mouse);
REPEAT GetMouse(mouse,x,y) UNTIL ML IN mouse;
REPEAT GetMouse(mouse,x,y) UNTIL NOT(ML IN mouse);
IdentifyPos(w,x,y);
i := x; j := y;
END GetPos;
PROCEDURE SANE(VAR e: BITSET; OpWord: CARDINAL); CODE 0A9EBH;
PROCEDURE SaveFPEnv;
BEGIN SANE(environ, 3)
END SaveFPEnv;
PROCEDURE ClearFPEnv;
VAR e: BITSET;
BEGIN e := {}; SANE(e, 1)
END ClearFPEnv;
PROCEDURE RestoreFPEnv;
VAR e: BITSET;
BEGIN e := environ; SANE(e, 1)
END RestoreFPEnv;
PROCEDURE Calculate;
VAR x,y: REAL; ix,iy: INTEGER;
PROCEDURE iteration(pe,qe,xe,ye: REAL) : INTEGER;
VAR a,y1,y2,x1,x2: REAL; counter: INTEGER;
BEGIN
IF xe = ye THEN RETURN maxiter END;
x1 := xe;
x2 := ye;
counter := 0;
y1 := f(x1);
y2 := f(x2);
REPEAT
a := y1 - y2;
IF a = 0.0 THEN RETURN maxiter END;
a := a / (x1 - x2);
x2 := x1; y2 := y1;
x1 := x1 - y1/a;
y1 := f(x1);
INC(counter);
UNTIL (ABS(y1) < max) OR (counter >= maxiter);
RETURN counter
END iteration;
BEGIN (* Calculate *)
SaveFPEnv;
ClearFPEnv;
dx := (xmax-xmin) / FLOAT(NrPixels);
dy := (ymax-ymin) / FLOAT(NrPixels);
y := ymin;
FOR iy := 0 TO NrPixels-1 DO
x := xmin;
FOR ix := 0 TO NrPixels-1 DO
this := iteration(p,q,x,y);
SetWindow(w);
Colour(this);
Dot(w,ix,iy);
ResetWindow;
x := x + dx;
END;
y := y + dy;
BusyRead(ch); IF (ch = ' ') THEN iy := NrPixels END;
END;
RestoreFPEnv;
END Calculate;
PROCEDURE ShowFunction(v: Window);
VAR ix,iy: INTEGER; x,y,y0,fmin,fmax,ry: REAL;
a: ARRAY [0..NrPixels] OF REAL;
BEGIN
SaveFPEnv;
ClearFPEnv;
fmin := 0.0; fmax := 0.0;
FOR ix := 0 TO NrPixels DO
x := xmin + FLOAT(ix) * ( (xmax-xmin) / FLOAT(NrPixels) );
y := f(x); a[ix] := y;
IF y > fmax THEN fmax := y
ELSIF y < fmin THEN fmin := y
END;
END;
FOR ix := 0 TO NrPixels DO a[ix] := a[ix] - fmin END;
FOR iy := 0 TO NrPixels DO
SetWindow(v);
ForeColour(zyan);
Dot(v, NrPixels DIV 2, iy);
ResetWindow;
END;
ry := ABS(fmax-fmin);
y0 := ABS(fmin) / ry * FLOAT(NrPixels);
iy := TRUNC(y0);
FOR ix := 0 TO NrPixels DO
SetWindow(v);
ForeColour(zyan);
Dot(v, ix, iy);
ResetWindow;
END;
FOR ix := 0 TO NrPixels DO
y := (a[ix] / ry) * FLOAT(NrPixels);
iy := TRUNC(y);
SetWindow(v);
ForeColour(red);
Dot(v, ix, iy);
ResetWindow;
END;
RestoreFPEnv;
END ShowFunction;
BEGIN
max := 1.0E-5;
maxiter := 255;
xmax := 4.0; xmin := -4.0;
ymax := 4.0; ymin := -4.0;
p := 0.0; q := 0.0;
OpenGraphicWindow(v,40,20,NrPixels+4,NrPixels+20,"Funktion",Clear);
Clear(v);
ShowFunction(v);
OpenGraphicWindow(w,330,100,NrPixels+2,NrPixels+20,"Newton",Clear);
Clear(w);
LOOP
WriteString ('drawing Newton.'); WriteLn;
Calculate; ch := 0C;
WriteString ('zoom requested Y/N:');
Read(ch); Write(ch); WriteLn;
IF CAP(ch) # "Y" THEN EXIT END;
WriteString ('define window !'); WriteLn;
GetPos(ox,oy);
ux := xmin + FLOAT(ox)*dx;
uy := ymin + FLOAT(oy)*dy;
GetPos(nx,ny);
deltax := ABS(nx-ox);
uux := xmin + FLOAT(nx)*dx;
uuy := uy + FLOAT(deltax)*dy;
xmin := ux; xmax := uux;
ymin := uy; ymax := uuy;
SetWindow(w);
ForeColour(black);
SetPen(w,ox,oy); MoveTo(w,nx,oy);
SetPen(w,nx,oy); MoveTo(w,nx,oy+deltax);
SetPen(w,nx,oy+deltax); MoveTo(w,ox,oy+deltax);
SetPen(w,ox,oy+deltax); MoveTo(w,ox,oy);
ResetWindow;
GetPos(ox,oy); (* wait for mouse click *)
Clear(w);
END;
CloseGraphicWindow(w);
CloseGraphicWindow(v);
END Newton.